/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License.  You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/


/*************************************************************************
 * File: exdata_wrapper.cpp
 *************************************************************************
 *\author: starlove
 *************************************************************************/

#include <codec/exdata_wrapper.h>

CMapWrapper::CMapWrapper()
{
    Reset();
}

CMapWrapper::CMapWrapper(bool f)
{
	if(f)
		Reset();
}

void CMapWrapper::Reset()
{
	m_tmpbuffer.Align(m_tmpbuffer.GetDataSize());
    //m_buffer.init(m_szTempBuffer, __BUFFER_SIZE__);
    WRAPPER_DATA_HEADER header;
    header.tp = DTP_MAP;
    header.size = 0;
    //if( m_buffer.alloc(sizeof(header)) )
    //{
        //m_buffer.push(&header, sizeof(header));
        //m_buffer.flush();
        //m_header = (LPWRAPPER_DATA_HEADER)m_buffer.data;
    //}
    //else
    //{
    //    m_header = NULL;
    //}
	m_tmpbuffer.Append(&header, sizeof(header));
	m_header = (LPWRAPPER_DATA_HEADER)m_tmpbuffer.GetPtr();
}

LPBUFFER_WRAPPER CMapWrapper::GetBuffer()
{
    m_buffer.readonly_ref(m_tmpbuffer.GetPtr(), m_tmpbuffer.GetDataSize());
    return &m_buffer;
}

bool CMapWrapper::Add(const void *pKey, unsigned int nKeySize, const void *pValue, unsigned int nSize, DATA_TP ktp, DATA_TP tp)
{
    WRAPPER_KEYVALUE_DATA_HEADER kv_header;
    kv_header.tp = tp;
    kv_header.ktp = ktp;
    kv_header.size = nSize;
    kv_header.ksize = nKeySize;

    const void *pData		= pValue;
    const void *pKeyData	= pKey;

    if (ktp == DTP_STR)
    {
        ENCODESTR pKeyStr = *(ENCODESTR *)pKey;
        kv_header.ksize = strlen(pKeyStr) + 1;
        pKeyData = pKeyStr;
    }else if (ktp == DTP_FLOAT || ktp == DTP_DOUBLE)
    {
        return false;
    }

    switch (tp)
    {
    case DTP_BUFFER:
    {
        LPBUFFER_WRAPPER pBuffer = (LPBUFFER_WRAPPER)pValue;
        kv_header.size = pBuffer->data_size();
        pData = pBuffer->data;
    }
    break;
    case DTP_PBUFFER:
    {
        LPBUFFER_WRAPPER pBuffer = *(LPBUFFER_WRAPPER *)pValue;
        kv_header.size = pBuffer->data_size();
        pData = pBuffer->data;
    }
    break;
    case DTP_STR:
    {
        ENCODESTR pBuffer = *(ENCODESTR *)pValue;
        kv_header.size = strlen(pBuffer) + 1;
        pData = pBuffer;
    }
    break;
    default:
    {}
    }
    //unsigned int nTotalSize = sizeof(kv_header) + kv_header.ksize + kv_header.size;

    //if(m_buffer.alloc(nTotalSize))
    //{
    //    m_buffer.push(&kv_header, sizeof(kv_header));
    //    m_buffer.push(pKeyData, kv_header.ksize);
    //    m_buffer.push(pData, kv_header.size);
    //    m_buffer.flush();
    //    m_header->size ++;
    //    return true;
    //}
    //else
    //{
    //    return false;
    //}
    m_tmpbuffer.Append(&kv_header, sizeof(kv_header));
    m_tmpbuffer.Append(pKeyData, kv_header.ksize);
    m_tmpbuffer.Append(pData, kv_header.size);
    m_header->size ++;
    return true;
}

CListWrapper::CListWrapper()
{
    Reset();
}

void CListWrapper::Reset()
{
	m_tmpbuffer.Align(m_tmpbuffer.GetDataSize());
	WRAPPER_DATA_HEADER header;
    header.tp = DTP_LIST;
    header.size = 0;
	m_tmpbuffer.Append(&header, sizeof(header));
	m_header = (LPWRAPPER_DATA_HEADER)m_tmpbuffer.GetPtr();
}

LPBUFFER_WRAPPER CListWrapper::GetBuffer()
{
    m_buffer.readonly_ref(m_tmpbuffer.GetPtr(), m_tmpbuffer.GetDataSize());
    return &m_buffer;
}

bool CListWrapper::Add(const void *pValue, unsigned int nSize, DATA_TP tp)
{
    WRAPPER_DATA_HEADER lst_header;
    lst_header.tp = tp;
    lst_header.size = nSize;

    const void *pData = pValue;

    switch (tp)
    {
    case DTP_BUFFER:
    {
        LPBUFFER_WRAPPER pBuffer = (LPBUFFER_WRAPPER)pValue;
        lst_header.size = pBuffer->data_size();
        pData = pBuffer->data;
    }
    break;
    case DTP_PBUFFER:
    {
        LPBUFFER_WRAPPER pBuffer = *(LPBUFFER_WRAPPER *)pValue;
        lst_header.size = pBuffer->data_size();
        pData = pBuffer->data;
    }
    break;
    case DTP_STR:
    {
        ENCODESTR pBuffer = *(ENCODESTR *)pValue;
        lst_header.size = strlen(pBuffer) + 1;
        pData = pBuffer;
    }
    break;
    default:
    {}
    }
    m_tmpbuffer.Append(&lst_header, sizeof(lst_header));
    m_tmpbuffer.Append(pData, lst_header.size);
    m_header->size ++;
        return true;
}
